package com.bytic.miaosha.interceptor;

import com.bytic.miaosha.annotation.AccessLimit;
import com.bytic.miaosha.business.MiaoshaBusiness;
import com.bytic.miaosha.componet.UserContext;
import com.bytic.miaosha.constant.KeyConstant;
import com.bytic.miaosha.domain.MiaoshaUser;
import com.bytic.miaosha.redis.AccessKey;
import com.bytic.miaosha.result.CodeMsg;
import com.bytic.miaosha.service.MiaoshaUserService;
import com.bytic.miaosha.business.WebBusiness;
import com.bytic.miaosha.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class AccessInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private MiaoshaUserService userService;

    @Autowired
    private RedisService redisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
            Exception {
        if (handler instanceof HandlerMethod) {
            MiaoshaUser user = getMiaoshaUser(request, response);
            UserContext.setUser(user);
            HandlerMethod method = (HandlerMethod) handler;
            AccessLimit methodAnnotation = method.getMethodAnnotation(AccessLimit.class);
            if (methodAnnotation == null) {
                return true;
            }
            boolean needLogin = methodAnnotation.needLogin();
            String key = request.getRequestURI();
            if (needLogin) { // 是否需要登录
                if (user == null) {
                    WebBusiness.render(response, CodeMsg.SESSION_ERROR);
                    return false;
                }
                key += "_" + user.getId();
            } else {
                // TODO someting
            }
            int secondes = methodAnnotation.seconds();
            int maxCount = methodAnnotation.maxCount();
            // 限制访问次数
            AccessKey access = AccessKey.withExpire(secondes);
            Integer count = redisService.get(access, key, Integer.class);
            if (count == null) {
                redisService.set(access, key, 1);
            } else if (count < maxCount) {
                redisService.incr(access, key);
            } else {
                WebBusiness.render(response, CodeMsg.ACCESS_LIMIT_REACHED);
                return false;
            }
        }
        return true;
    }

    private MiaoshaUser getMiaoshaUser(HttpServletRequest request, HttpServletResponse response) {
        String paramToken = request.getParameter(KeyConstant.COOKIE_NAME_TOKEN);
        String cookieToken = MiaoshaBusiness.getCookieToken(request, KeyConstant.COOKIE_NAME_TOKEN);
        if (StringUtils.isEmpty(paramToken) && StringUtils.isEmpty(cookieToken)) {
            return null;
        }
        String token = StringUtils.isEmpty(paramToken) ? cookieToken : paramToken;
        // 获取用户
        return userService.getUserByToken(response, token);
    }
}
